package com.alibaba.citrus.cr.mn.order.center.facade.function.impl;

import cn.hutool.core.date.StopWatch;
import com.alibaba.citrus.cr.common.enums.ordercenter.DictionaryTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.ReturnOrderTypeEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.SetOrderTag;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.BaseDataServiceAdapter;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.CustomerSaleScopeAdapter;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.DictionaryVerifyAdapter;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.OrderAtomQueryService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.AtomOrderDOToReturnOrderAtomQueryResponseConvertor;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.BeanConverter;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.PageQuerySaleOrderDetailCovert;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor;
import com.alibaba.citrus.cr.mn.order.center.facade.function.dataobject.AtomOrderDO;
import com.alibaba.citrus.cr.mn.order.center.facade.repository.AtomOrderQueryRepository;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.domain.order.dto.QueryByOrderNosRequest;
import com.epoch.app.crb2btradecenter.model.dto.PageQueryOrderEsListRequest4OrderCenter;
import com.epoch.app.crb2btradecenter.model.dto.PageQuerySaleOrderDetailGroupRequest;
import com.epoch.app.crb2btradecenter.obtcsaleorderindex.model.ObtcSaleOrderIndex;
import com.epoch.app.crb2btradecenter.obtcsaleorderindex.service.ObtcSaleOrderIndexService;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.dto.QueryOrderLineByMainIds4OrderCenterRequest;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.model.ObtcSaleOrderLineIndex;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.service.ObtcSaleOrderLineIndexService;
import com.epoch.app.mnordercenter.contants.MnOrderCenterConstants;
import com.epoch.app.mnordercenter.model.dto.DictionaryResponse;
import com.epoch.app.mnordercenter.model.dto.OrderAtomQueryListRequest;
import com.epoch.app.mnordercenter.model.dto.ReturnOrderAtomQueryResponse;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomPageQueryRequest;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Chen.mu
 * 2023/5/11
 **/
@Service("returnOrderAtomQueryService")
public class ReturnOrderAtomQueryServiceImpl implements OrderAtomQueryService<OrderAtomQueryListRequest, SalesOrderAtomPageQueryRequest, ReturnOrderAtomQueryResponse> {
    private static final Log log = Log.getLogger(SalesOrderAtomQueryServiceImpl.class);
    @Resource
    private AtomOrderQueryRepository atomOrderQueryRepository;

    @Resource
    private CustomerSaleScopeAdapter customerSaleScopeAdapter;

    @Resource
    private BaseDataServiceAdapter baseDataServiceAdapter;

    @Resource
    private ObtcSaleOrderIndexService obtcSaleOrderIndexService;

    @Resource
    private ObtcSaleOrderLineIndexService obtcSaleOrderLineIndexService;

    @Resource
    private DictionaryVerifyAdapter dictionaryVerifyAdapter;
    @Override
    public PageResult<List<ReturnOrderAtomQueryResponse>> listPage(OrderAtomQueryListRequest queryRequest) {
        log.info("Order_listPage_Request request={}", JSONObject.toJSON(queryRequest));

        filterBlankOrderNo(queryRequest);
        if (queryRequest.getPage() == null) {
            queryRequest.setPage(1);
        }
        if (queryRequest.getSize() == null) {
            queryRequest.setSize(10);
        }
        paramsCheck(queryRequest);
        if (CollectionUtils.isNotEmpty(queryRequest.getDeliveryOrderNo())) {
            return PageResult.of(Lists.newArrayList(), 0);
        }

        QueryByOrderNosRequest request = QueryByOrderNosRequest.builder().build();
        BeanConverter.convert(queryRequest, request);
        request.setSalesOrderNo(queryRequest.getSalesOrderNo());
        //改用setBusinessUnitOutCode查 因6255会查出来2个businessUnitcode
        request.setPreOrderNos(queryRequest.getPreOrderNo());
        request.setBusinessUnitOutCode(queryRequest.getBusinessUnitCode());
        request.setBusinessUnitCode(null);
        request.setOrderTag(SetOrderTag.RETURN);

        Result<List<AtomOrderDO>> listResult = atomOrderQueryRepository.queryByOrderNos(request);
        log.info("Order_listPage_Request={}，size={}", JSONObject.toJSON(request), listResult.getTotal());

        List<ReturnOrderAtomQueryResponse> result =
                AtomOrderDOToReturnOrderAtomQueryResponseConvertor.convert(listResult.getResult());
        if (CollectionUtils.isEmpty(result)) {
            return PageResult.of(result, listResult.getTotal());
        }
        List<DictionaryResponse> businessTypeResponseList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.BUSINESS_TYPE.getCode());
        Map<String, DictionaryResponse> businessTypeMap = businessTypeResponseList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (k1, k2) -> k2));
        for (ReturnOrderAtomQueryResponse returnOrder : result) {
            if (returnOrder.getBusinessType() != null && businessTypeMap.containsKey(returnOrder.getBusinessType().toString())) {
                returnOrder.setBusinessTypeName(businessTypeMap.get(returnOrder.getBusinessType().toString()).getName());
            }
        }
        return PageResult.of(result, listResult.getTotal());
    }

    @Override
    public PageResult<List<ReturnOrderAtomQueryResponse>> page(SalesOrderAtomPageQueryRequest request, String orderTag) {
        log.info("Order_Page_Request request={}", JSONObject.toJSON(request));
        if(request.getPage()==null){
            request.setPage(1);
        }
        if(request.getSize()==null){
            request.setSize(10);
        }
//        AssertUtils.lengthCheck(request.getFromSys(), 50, false, "OC-01-001-01-15-004", "系统来源编码");
//        baseParamsCheck(request.getFromSys(),
//                request.getBusinessUnitCode(),
//                request.getBusinessType(),
//                request.getPage(),
//                request.getSize());

        baseAtomParamsCheck(request);

        AssertUtils.lengthCheck(request.getShipToPartyCode(), 50, false, "OC-01-001-01-15-004", "送达方编码");
        AssertUtils.lengthCheck(request.getCustomerCode(), 50, false, "OC-01-001-01-15-004", "售达方编码");
        AssertUtils.lengthCheck(request.getSalesOrganizationCode(), 50, false, "OC-01-001-01-15-004", "销售组织编码");
        AssertUtils.lengthCheck(request.getProductGroupCode(), 50, false, "OC-01-001-01-15-004", "产品组编码");
        AssertUtils.lengthCheck(request.getCreateBeginTime(), 19, false, "OC-01-001-01-15-004", "创建开始日期");
        AssertUtils.lengthCheck(request.getCreateEndTime(), 19, false, "OC-01-001-01-15-004", "创建结束日期");
        AssertUtils.lengthCheck(request.getModifyBeginTime(), 19, false, "OC-01-001-01-15-004", "修改开始日期");
        AssertUtils.lengthCheck(request.getModifyEndTime(), 19, false, "OC-01-001-01-15-004", "修改结束日期");
        AssertUtils.lengthCheck(request.getExpectedDeliveryBeginDate(), 10, false, "OC-01-001-01-15-004", "期望交货开始日期");
        AssertUtils.lengthCheck(request.getExpectedDeliveryEndDate(), 10, false, "OC-01-001-01-15-004", "期望交货结束日期");
        if(CollectionUtils.isNotEmpty(request.getSalesOrderNoList())){
            AssertUtils.isTrue(request.getSalesOrderNoList().size() > 10, "OC-01-001-01-15-004", "销售订单号集合", request.getSalesOrderNoList().size(), 10);
            request.getSalesOrderNoList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "销售订单号");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getOriginalOrderNoList())){
            AssertUtils.isTrue(request.getOriginalOrderNoList().size() > 10, "OC-01-001-01-15-004", "原销售订单号集合", request.getOriginalOrderNoList().size(), 10);
            request.getOriginalOrderNoList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "原销售订单号");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getOutOrderNoList())){
            AssertUtils.isTrue(request.getOutOrderNoList().size() > 10, "OC-01-001-01-15-004", "外部单号集合", request.getOutOrderNoList().size(), 10);
            request.getOutOrderNoList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "外部单号");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getSourceOrderNoList())){
            AssertUtils.isTrue(request.getSourceOrderNoList().size() > 10, "OC-01-001-01-15-004", "来源单号集合", request.getSourceOrderNoList().size(), 10);
            request.getSourceOrderNoList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "来源单号");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getSalesOrderType())){
            request.getSalesOrderType().stream().forEach(x->{
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "订单类型编码");
                ReturnOrderTypeEnum salesOrderTypeEnum=ReturnOrderTypeEnum.of(x);
                AssertUtils.isTrue(salesOrderTypeEnum==null, "OC-01-001-01-15-009", "订单类型编码", x);
            });
        }
        if(CollectionUtils.isNotEmpty(request.getStatusList())){
            AssertUtils.isTrue(request.getStatusList().size() > 10, "OC-01-001-01-15-004", "订单状态集合", request.getStatusList().size(), 10);
            request.getStatusList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "订单状态");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getDeliveryMethodCodeList())){
            AssertUtils.isTrue(request.getDeliveryMethodCodeList().size() > 10, "OC-01-001-01-15-004", "配送方式编码集合", request.getDeliveryMethodCodeList().size(), 10);
            request.getDeliveryMethodCodeList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "配送方式编码");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getOrderReasonCodeList())){
            AssertUtils.isTrue(request.getOrderReasonCodeList().size() > 10, "OC-01-001-01-15-004", "订单原因编码集合", request.getOrderReasonCodeList().size(), 10);
            request.getOrderReasonCodeList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "订单原因编码");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getCloseReasonCodeList())){
            AssertUtils.isTrue(request.getCloseReasonCodeList().size() > 10, "OC-01-001-01-15-004", "关闭原因编码集合", request.getCloseReasonCodeList().size(), 10);
            request.getCloseReasonCodeList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "关闭原因编码");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getProductCodeList())){
            AssertUtils.isTrue(request.getProductCodeList().size() > 10, "OC-01-001-01-15-004", "物料编码集合", request.getProductCodeList().size(), 10);
            request.getProductCodeList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "物料编码");
            });
        }
        if(CollectionUtils.isNotEmpty(request.getShippingWarehouseCodeList())){
            AssertUtils.isTrue(request.getShippingWarehouseCodeList().size() > 10, "OC-01-001-01-15-004", "收货仓库编码集合", request.getShippingWarehouseCodeList().size(), 10);
            request.getShippingWarehouseCodeList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "收货仓库编码");
            });
        }
        AssertUtils.lengthCheck(request.getDeliveryFactoryCode(), 50, false, "OC-01-001-01-15-004", "收货工厂编码");
        AssertUtils.lengthCheck(request.getStockCode(), 50, false, "OC-01-001-01-15-004", "收货库存地点编码");
        AssertUtils.lengthCheck(request.getCreatorCode(), 50, false, "OC-01-001-01-15-004", "创建人工号");
        AssertUtils.lengthCheck(request.getModifierCode(), 50, false, "OC-01-001-01-15-004", "修改人工号");
        AssertUtils.lengthCheck(request.getCustomerPurchaseOrderNo(), 50, false, "OC-01-001-01-15-004", "客户采购订单号");
        if (CollectionUtils.isNotEmpty(request.getReceiveStatusList())) {
            AssertUtils.isTrue(request.getReceiveStatusList().size() > 10, "OC-01-001-01-15-004", "收货状态集合", request.getReceiveStatusList().size(), 10);
            request.getReceiveStatusList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "收货状态");
            });
        }
        AssertUtils.lengthCheck(request.getNote(), 255, false, "OC-01-001-01-15-004", "备注（主单）");
        if (CollectionUtils.isNotEmpty(request.getBusinessChannel())) {
            AssertUtils.isTrue(request.getBusinessChannel().size() > 10, "OC-01-001-01-15-004", "业务渠道编码集合", request.getBusinessChannel().size(), 10);
            request.getBusinessChannel().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "业务渠道编码");
            });
        }
        if (CollectionUtils.isNotEmpty(request.getSalesDepartmentCode())) {
            AssertUtils.isTrue(request.getSalesDepartmentCode().size() > 10, "OC-01-001-01-15-004", "销售部门编码集合", request.getSalesDepartmentCode().size(), 10);
            request.getSalesDepartmentCode().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "销售部门编码");
            });
        }
        if (CollectionUtils.isNotEmpty(request.getSalesChannelCode())) {
            AssertUtils.isTrue(request.getSalesChannelCode().size() > 10, "OC-01-001-01-15-004", "销售渠道编码集合", request.getSalesChannelCode().size(), 10);
            request.getSalesChannelCode().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "销售渠道编码");
            });
        }
        if (CollectionUtils.isNotEmpty(request.getSalesOrderType())) {
            AssertUtils.isTrue(request.getSalesOrderType().size() > 10, "OC-01-001-01-15-004", "订单类型编码集合", request.getSalesOrderType().size(), 10);
            request.getSalesOrderType().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "订单类型编码");
            });
        }
        if (CollectionUtils.isNotEmpty(request.getKaAreaList())) {
            AssertUtils.isTrue(request.getKaAreaList().size() > 10, "OC-01-001-01-15-004", "KA大区集合", request.getKaAreaList().size(), 10);
            request.getKaAreaList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "KA大区");
            });
        }
        if (CollectionUtils.isNotEmpty(request.getKaSystemList())) {
            AssertUtils.isTrue(request.getKaSystemList().size() > 10, "OC-01-001-01-15-004", "KA系统集合", request.getKaSystemList().size(), 10);
            request.getKaSystemList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "KA系统");
            });
        }
        if (CollectionUtils.isNotEmpty(request.getReceiveWarehouseCodeList())) {
            AssertUtils.isTrue(request.getReceiveWarehouseCodeList().size() > 10, "OC-01-001-01-15-004", "收货仓（逻辑仓库编码）集合", request.getReceiveWarehouseCodeList().size(), 10);
            request.getReceiveWarehouseCodeList().stream().forEach(x-> {
                AssertUtils.lengthCheck(x, 50,false,"OC-01-001-01-15-004", "收货仓（逻辑仓库编码）");
            });
        }
        Date startDate = DateUtils.getBeginOrEndByStr(request.getCreateBeginTime(),true);
        Date endDate = DateUtils.getBeginOrEndByStr(request.getCreateEndTime(),false);
        if(startDate != null && endDate != null){
            AssertUtils.isTrue(startDate.after(endDate), "OC-01-001-01-15-011");
        }
        //传入的时间不为空，但格式化后为空， 说明时间格式化失败 报错出去
        AssertUtils.isTrue(StringUtils.isNotBlank(request.getCreateBeginTime())&&startDate==null, "OC-00-001-01-15-001","创建开始时间");
        AssertUtils.isTrue(StringUtils.isNotBlank(request.getCreateEndTime())&&endDate==null, "OC-00-001-01-15-001","创建结束时间");
        request.setCreateBeginTime(DateUtils.toDateStr(startDate, DateUtils.DATETIME_FORMAT));
        request.setCreateEndTime(DateUtils.toDateStr(endDate, DateUtils.DATETIME_FORMAT));

        Date modifyBeginTime = DateUtils.getBeginOrEndByStr(request.getModifyBeginTime(),true);
        Date modifyEndTime = DateUtils.getBeginOrEndByStr(request.getModifyEndTime(),false);
        if(modifyBeginTime != null && modifyEndTime != null){
            AssertUtils.isTrue(modifyBeginTime.after(modifyEndTime), "OC-01-001-01-15-011");
        }
        //传入的时间不为空，但格式化后为空， 说明时间格式化失败 报错出去
        AssertUtils.isTrue(StringUtils.isNotBlank(request.getModifyBeginTime()) && modifyBeginTime == null, "OC-00-001-01-15-001","修改开始时间");
        AssertUtils.isTrue(StringUtils.isNotBlank(request.getModifyEndTime()) && modifyEndTime == null, "OC-00-001-01-15-001","修改结束时间");
        request.setModifyBeginTime(DateUtils.toDateStr(modifyBeginTime, DateUtils.DATETIME_FORMAT));
        request.setModifyEndTime(DateUtils.toDateStr(modifyEndTime, DateUtils.DATETIME_FORMAT));

        Date expectedDeliveryBeginDate = DateUtils.getBeginOrEndByStr(request.getExpectedDeliveryBeginDate(),true);
        Date expectedDeliveryEndDate = DateUtils.getBeginOrEndByStr(request.getExpectedDeliveryEndDate(),false);
        if(expectedDeliveryBeginDate != null && expectedDeliveryEndDate != null){
            AssertUtils.isTrue(expectedDeliveryBeginDate.after(expectedDeliveryEndDate), "OC-01-001-01-15-011");
        }
        //传入的时间不为空，但格式化后为空， 说明时间格式化失败 报错出去
        AssertUtils.isTrue(StringUtils.isNotBlank(request.getExpectedDeliveryBeginDate()) && expectedDeliveryBeginDate == null, "OC-00-001-01-15-001","期望交货开始日期");
        AssertUtils.isTrue(StringUtils.isNotBlank(request.getExpectedDeliveryEndDate()) && expectedDeliveryEndDate == null, "OC-00-001-01-15-001","期望交货结束日期");
        request.setExpectedDeliveryBeginDate(DateUtils.toDateStr(expectedDeliveryBeginDate, DateUtils.DATE_FORMAT));
        request.setExpectedDeliveryEndDate(DateUtils.toDateStr(expectedDeliveryEndDate, DateUtils.DATE_FORMAT));
        //改用setBusinessUnitOutCode查
        //convertRequest(salesOrderAtomPageQueryRequest);

        return pageQueryByEs(request, orderTag);
    }

    @Override
    public PageResult<List<ReturnOrderAtomQueryResponse>> listPageForInner(OrderAtomQueryListRequest queryRequest) {
        //使用到时再实现
        return null;
    }

    @Override
    public Result<List<ObtcSaleOrderLineIndex>> detailListPage(SalesOrderAtomPageQueryRequest request) {
        log.info("ReturnOrderAtomQueryServiceImpl#detailListPage request={}", JSONObject.toJSON(request));
        if (request.getPage() == null) {
            request.setPage(1);
        }
        if (request.getSize() == null) {
            request.setSize(10);
        }
        PageQuerySaleOrderDetailGroupRequest esRequest = PageQuerySaleOrderDetailCovert.covert(request);
        log.info("ReturnOrderAtomQueryServiceImpl#pageQueryByEs esRequest:{};", JSON.toJSONString(esRequest));
        Result<List<ObtcSaleOrderLineIndex>> listResult = obtcSaleOrderLineIndexService.pageOrderLineList(esRequest);
        log.info("ReturnOrderAtomQueryServiceImpl#pageQueryByEs listResult:{};", JSON.toJSONString(listResult));
        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
            listResult.setSuccess(true);
        }
        return listResult;
    }

    private void convertRequest(SalesOrderAtomPageQueryRequest salesOrderAtomPageQueryRequest) {
        List<String> bisUnitCodes = Lists.newArrayList(salesOrderAtomPageQueryRequest.getBusinessUnitCode());
        Map<String, String> organizationMap = baseDataServiceAdapter.baselineGetOrganizationByCodes2(bisUnitCodes);
        if (MapUtils.isEmpty(organizationMap)) {
            throw new FunctionException("OC-01-001-01-16-011", salesOrderAtomPageQueryRequest.getBusinessUnitCode());
        }
        String orgId = organizationMap.get(salesOrderAtomPageQueryRequest.getBusinessUnitCode());
        if (StringUtils.isBlank(orgId)) {
            throw new FunctionException("OC-01-001-01-16-011", salesOrderAtomPageQueryRequest.getBusinessUnitCode());
        }
        salesOrderAtomPageQueryRequest.setBusinessUnitCode(orgId);
    }

    private PageResult<List<ReturnOrderAtomQueryResponse>> pageQueryByEs(SalesOrderAtomPageQueryRequest pageRequest, String orderTag) {
        StopWatch stopWatch = new StopWatch("退货订单批量查询");

        stopWatch.start("buildPageQueryOrderEsListRequest");
        PageQueryOrderEsListRequest4OrderCenter request = buildPageQueryOrderEsListRequest(pageRequest);
        stopWatch.stop();

        if (StringUtils.isNotBlank(orderTag)) {
            request.setOrderTag(orderTag);
        }

        stopWatch.start("pageQueryOrderList4OrderCenter");
        request.setBusinessUnitOutCode(request.getBusinessUnitCode());
        request.setBusinessUnitCode(null);
        Result<List<ObtcSaleOrderIndex>> listResult = obtcSaleOrderIndexService.pageQueryOrderList4OrderCenter(request);
        log.info("Order_Page_Main_Request request={}", JSONObject.toJSON(request));
        log.info("listResult结果={}", JSONObject.toJSONString(listResult));
        stopWatch.stop();

        List<ReturnOrderAtomQueryResponse> responses;
        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
            List<Long> mainIds = listResult.getResult().stream().map(ObtcSaleOrderIndex::getMainId).collect(Collectors.toList());
            QueryOrderLineByMainIds4OrderCenterRequest lineRequest = new QueryOrderLineByMainIds4OrderCenterRequest();
            lineRequest.setMainIdList(mainIds);
            lineRequest.setLimit(mainIds.size() * 10);//按主单条数的 10倍量 查明细

            stopWatch.start("queryOrderLineByMainIds4OrderCenter");
            Result<List<ObtcSaleOrderLineIndex>> lineResult =
                    obtcSaleOrderLineIndexService.queryOrderLineByMainIds4OrderCenter(lineRequest);
            log.info("Order_Page_Line_Request request={}", JSONObject.toJSON(lineRequest));
            stopWatch.stop();

            stopWatch.start("convert");
            responses = ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor.convert(listResult, lineResult);
            stopWatch.stop();
        } else {
            stopWatch.start("convertMainOrder");
            responses = ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor.convertMainOrder(listResult);
            stopWatch.stop();
        }

        log.info("ExchangeOrderAtomQueryServiceImpl#pageQueryByEs stopWatch.getTotalTimeSeconds()={}", stopWatch.getTotalTimeSeconds());
        log.info("ExchangeOrderAtomQueryServiceImpl#pageQueryByEs stopWatch.prettyPrint()={}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));

        return PageResult.of(responses, listResult.getTotal());
    }

    @NotNull
    private PageQueryOrderEsListRequest4OrderCenter buildPageQueryOrderEsListRequest(SalesOrderAtomPageQueryRequest pageRequest) {
        PageQueryOrderEsListRequest4OrderCenter esRequest = new PageQueryOrderEsListRequest4OrderCenter();
        esRequest.setDir("main_gmt_create");
        String fromSys = pageRequest.getFromSys();
        String businessType = pageRequest.getBusinessType();
        String businessUnitCode = pageRequest.getBusinessUnitCode();
        String createTimeStart = pageRequest.getCreateBeginTime();
        String createTimeEnd = pageRequest.getCreateEndTime();
        List<String> salesOrderType = pageRequest.getSalesOrderType();
        String customerCode = pageRequest.getCustomerCode();
        String shipToPartyCode = pageRequest.getShipToPartyCode();
        String salesOrganizationCode = pageRequest.getSalesOrganizationCode();
        List<String> salesChannelCode = pageRequest.getSalesChannelCode();
        List<String> salesDepartmentCode = pageRequest.getSalesDepartmentCode();
        String productGroupCode = pageRequest.getProductGroupCode();
        List<String> statusList = pageRequest.getStatusList();
        List<String> businessChannel = pageRequest.getBusinessChannel();
        List<String> productCodeList = pageRequest.getProductCodeList();
        String productName = pageRequest.getProductName();
        List<String> outOrderNoList = pageRequest.getOutOrderNoList();
        List<String> sourceOrderNoList = pageRequest.getSourceOrderNoList();
        List<String> salesOrderNoList = pageRequest.getSalesOrderNoList();
        List<String> originalOrderNoList = pageRequest.getOriginalOrderNoList();
        String customerPurchaseOrderNo = pageRequest.getCustomerPurchaseOrderNo();
        String modifyBeginTime = pageRequest.getModifyBeginTime();
        String modifyEndTime = pageRequest.getModifyEndTime();
        String expectedDeliveryBeginDate = pageRequest.getExpectedDeliveryBeginDate();
        String expectedDeliveryEndDate = pageRequest.getExpectedDeliveryEndDate();
        List<String> orderReasonCodeList = pageRequest.getOrderReasonCodeList();
        List<String> closeReasonCodeList = pageRequest.getCloseReasonCodeList();
        String note = pageRequest.getNote();
        String businessChannelCode = pageRequest.getBusinessChannelCode();
        List<String> shippingWarehouseCodeList = pageRequest.getShippingWarehouseCodeList();
        String deliveryFactoryCode = pageRequest.getDeliveryFactoryCode();
        String stockCode = pageRequest.getStockCode();
        String creatorCode = pageRequest.getCreatorCode();
        String modifierCode = pageRequest.getModifierCode();
        String contact = pageRequest.getContact();
        String contactPhone = pageRequest.getContactPhone();
        List<String> receiveStatusList = pageRequest.getReceiveStatusList();
        List<String> kaAreaList = pageRequest.getKaAreaList();
        List<String> kaSystemList = pageRequest.getKaSystemList();
        List<String> receiveWarehouseCodeList = pageRequest.getReceiveWarehouseCodeList();
        List<String> deliveryMethodCodeList = pageRequest.getDeliveryMethodCodeList();
        if (StringUtils.isNotBlank(fromSys)) {
            esRequest.setFromSys(fromSys);
        }
        if (StringUtils.isNotBlank(businessType)) {
            esRequest.setBusinessType(businessType);
        }
        if (StringUtils.isNotBlank(businessUnitCode)) {
            esRequest.setBusinessUnitCode(businessUnitCode);
        }
        try {
            if (StringUtils.isNotBlank(createTimeStart)) {
                esRequest.setOrderStartTime(DateUtils.formatString2Date(createTimeStart, "yyyy-MM-dd HH:mm:ss"));
            }
            if (StringUtils.isNotBlank(createTimeEnd)) {
                esRequest.setOrderEndTime(DateUtils.formatString2Date(createTimeEnd, "yyyy-MM-dd HH:mm:ss"));
            }
            if (StringUtils.isNotBlank(modifyBeginTime)) {
                esRequest.setUpdateStartTime(DateUtils.formatString2Date(modifyBeginTime, "yyyy-MM-dd HH:mm:ss"));
            }
            if (StringUtils.isNotBlank(modifyEndTime)) {
                esRequest.setUpdateEndTime(DateUtils.formatString2Date(modifyEndTime, "yyyy-MM-dd HH:mm:ss"));
            }
            if (StringUtils.isNotBlank(expectedDeliveryBeginDate)) {
                esRequest.setExpectedDeliveryBeginTime(DateUtils.formatString2Date(expectedDeliveryBeginDate, "yyyy-MM-dd"));
            }
            if (StringUtils.isNotBlank(expectedDeliveryEndDate)) {
                esRequest.setExpectedDeliveryEndTime(DateUtils.formatString2Date(expectedDeliveryEndDate, "yyyy-MM-dd"));
            }
        } catch (Exception e) {
            log.error("ExchangeOrderAtomQueryServiceImpl#buildPageQueryOrderEsListRequest error", e);
            throw new FunctionException("OC-00-001-01-15-001", "日期");
        }
        if (CollectionUtils.isNotEmpty(salesOrderType)) {
            esRequest.setOrderTypeList(salesOrderType);
        }
        if (CollectionUtils.isNotEmpty(statusList)) {
            esRequest.setMainStatusList(statusList);
        }
        if (StringUtils.isNotBlank(customerCode)) {
            esRequest.setCustomerCode(customerCode);
        }
        if (StringUtils.isNotBlank(shipToPartyCode)) {
            esRequest.setAddressCode(shipToPartyCode);
        }
        if (StringUtils.isNotBlank(salesOrganizationCode)) {
            esRequest.setSalesOrganizationOutCode(salesOrganizationCode);
        }
        if (CollectionUtils.isNotEmpty(salesChannelCode)) {
            esRequest.setSaleChannelOutCode(salesChannelCode);
        }
        if (CollectionUtils.isNotEmpty(salesDepartmentCode)) {
            esRequest.setSaleDepartmentOutCode(salesDepartmentCode);
        }
        if (StringUtils.isNotBlank(productGroupCode)) {
            esRequest.setProductGroupCode(productGroupCode);
        }
        if (CollectionUtils.isNotEmpty(businessChannel)) {
            esRequest.setBuzChannel(businessChannel);
        }
        if(CollectionUtils.isNotEmpty(productCodeList)){
            esRequest.setProductCodeList(productCodeList);
        }
        esRequest.setGoods(productName);
        if (CollectionUtils.isNotEmpty(originalOrderNoList)) {
            esRequest.setOriginalOrderNoList(originalOrderNoList);
        }
        if(CollectionUtils.isNotEmpty(sourceOrderNoList)){
            esRequest.setSourceOrderNoList(sourceOrderNoList);
        }
        if(CollectionUtils.isNotEmpty(outOrderNoList)){
            esRequest.setOuterIdList(outOrderNoList);
        }
        if(CollectionUtils.isNotEmpty(salesOrderNoList)){
            esRequest.setBizCodeList(salesOrderNoList);
        }
        esRequest.setCustomerPurchaseOrderNo(customerPurchaseOrderNo);
        if(CollectionUtils.isNotEmpty(orderReasonCodeList)){
            esRequest.setOrderReasonCodeList(orderReasonCodeList);
        }
        if(CollectionUtils.isNotEmpty(closeReasonCodeList)){
            esRequest.setCloseReasonCodeList(closeReasonCodeList);
        }
        esRequest.setOrderRemark(note);
        esRequest.setBusinessChannelCode(businessChannelCode);
        if(CollectionUtils.isNotEmpty(shippingWarehouseCodeList)){
            esRequest.setShippingWarehouseCodeList(shippingWarehouseCodeList);
        }
        esRequest.setDeliveryFactoryCode(deliveryFactoryCode);
        esRequest.setStockCode(stockCode);
        esRequest.setContactor(contact);
        esRequest.setPhone(contactPhone);
        esRequest.setCreatorCode(creatorCode);
        esRequest.setModifierCode(modifierCode);
        if(CollectionUtils.isNotEmpty(receiveStatusList)){
            esRequest.setSubStatusList(receiveStatusList);
        }
        if(CollectionUtils.isNotEmpty(kaAreaList)){
            esRequest.setKaAreaList(kaAreaList);
        }
        if(CollectionUtils.isNotEmpty(kaSystemList)){
            esRequest.setKaSystemList(kaSystemList);
        }
        if(CollectionUtils.isNotEmpty(receiveWarehouseCodeList)){
            esRequest.setReceiveWarehouseCodeList(receiveWarehouseCodeList);
        }
        if(CollectionUtils.isNotEmpty(deliveryMethodCodeList)){
            esRequest.setDeliveryMethodCodeList(deliveryMethodCodeList);
        }
        esRequest.setPage(pageRequest.getPage());
        esRequest.setSize(pageRequest.getSize());
        esRequest.setLimit(pageRequest.getSize());

        return esRequest;
    }


    private void convertRequest(OrderAtomQueryListRequest salesOrderAtomQueryListRequest) {
        List<String> bisUnitCodes = Lists.newArrayList(salesOrderAtomQueryListRequest.getBusinessUnitCode());
        Map<String, String> organizationMap = baseDataServiceAdapter.baselineGetOrganizationByCodes2(bisUnitCodes);
        if (MapUtils.isEmpty(organizationMap)) {
            throw new FunctionException("OC-01-001-01-16-011", salesOrderAtomQueryListRequest.getBusinessUnitCode());
        }
        String orgId = organizationMap.get(salesOrderAtomQueryListRequest.getBusinessUnitCode());
        if (StringUtils.isBlank(orgId)) {
            throw new FunctionException("OC-01-001-01-16-011", salesOrderAtomQueryListRequest.getBusinessUnitCode());
        }
        salesOrderAtomQueryListRequest.setBusinessUnitCode(orgId);
    }

    private void baseParamsCheck(String fromSys, String businessUnitCode, String businessType, int page, int size) {
        AssertUtils.isTrue(StringUtils.isBlank(businessUnitCode), "OC-01-001-01-15-001", "业务单元编码");
        AssertUtils.lengthCheck(businessUnitCode, 50, true, "OC-01-001-01-15-004", "业务单元编码");

        AssertUtils.isTrue(StringUtils.isBlank(businessType), "OC-01-001-01-15-001", "业态编码");
        AssertUtils.lengthCheck(businessType, 10, true, "OC-01-001-01-15-004", "业态编码");
        AssertUtils.isTrue(page > MnOrderCenterConstants.MAX_PAGE().intValue(), "OC-01-001-01-15-009", "页数", "最大"+MnOrderCenterConstants.MAX_PAGE().intValue());
        AssertUtils.isTrue(size >MnOrderCenterConstants.MAX_SIZE().intValue(), "OC-01-001-01-15-009", "分页条数", "最大"+MnOrderCenterConstants.MAX_SIZE().intValue());
        AssertUtils.isTrue(page <=0, "OC-01-001-01-15-009", "页数", "最小值为1");
        AssertUtils.isTrue(size<=0, "OC-01-001-01-15-009", "分页条数", "最小值为1");
        dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.BUSINESS_TYPE.getCode(), businessType, new FunctionException("OC-01-001-01-15-006", "业态编码"));
        if (StringUtils.isNotBlank(fromSys)) {
            dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.FROM_SYS.getCode(), fromSys, new FunctionException("OC-01-001-01-15-006", "来源系统编码"));
        }
    }


    private void baseAtomParamsCheck(SalesOrderAtomPageQueryRequest request) {
        AssertUtils.lengthCheck(request.getBusinessUnitCode(), 50, false, "OC-01-001-01-15-004", "业务单元编码");
        AssertUtils.lengthCheck(request.getFromSys(), 50, false, "OC-01-001-01-15-004", "来源系统编码");
        if(StringUtils.isNotBlank(request.getFromSys())) {
            dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.FROM_SYS.getCode(), request.getFromSys(), new FunctionException("OC-01-001-01-15-006", "来源系统编码"));
        }
        if(StringUtils.isNotBlank(request.getBusinessUnitCode())) {
            dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.BUSINESS_UNIT_CODE.getCode(), request.getBusinessUnitCode(), new FunctionException("OC-01-001-01-15-006", "业务单元编码"));
        }
        if (CollectionUtils.isNotEmpty(request.getFromSysList())) {
            AssertUtils.isTrue(request.getFromSysList().size() > 10, "OC-01-001-01-15-004", "来源系统编码集合", request.getFromSysList().size(), "10");
            checkItemLength(request.getFromSysList(), 50, "来源系统编码");
            request.getFromSysList().forEach(fromSys -> {
                dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.FROM_SYS.getCode(), fromSys, new FunctionException("OC-01-001-01-15-006", "来源系统编码"));
            });
        }
        if (CollectionUtils.isNotEmpty(request.getBusinessUnitCodeList())) {
            AssertUtils.isTrue(request.getBusinessUnitCodeList().size() > 10, "OC-01-001-01-15-004", "业务单元编码集合", request.getBusinessUnitCodeList().size(), "10");
            checkItemLength(request.getBusinessUnitCodeList(), 50, "业务单元编码");
            request.getBusinessUnitCodeList().forEach(businessUnitCode -> {
                dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.BUSINESS_UNIT_CODE.getCode(), businessUnitCode, new FunctionException("OC-01-001-01-15-006", "业务单元编码"));
            });
        }
        AssertUtils.isTrue(StringUtils.isBlank(request.getBusinessType()), "OC-01-001-01-15-001", "业态编码");
        AssertUtils.lengthCheck(request.getBusinessType(), 10, true, "OC-01-001-01-15-004", "业态编码");
        dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.BUSINESS_TYPE.getCode(), request.getBusinessType(), new FunctionException("OC-01-001-01-15-006", "业态编码"));
        AssertUtils.isTrue(request.getPage() > MnOrderCenterConstants.MAX_PAGE().intValue(), "OC-01-001-01-15-009", "页数", "最大"+MnOrderCenterConstants.MAX_PAGE().intValue());
        AssertUtils.isTrue(request.getSize() > MnOrderCenterConstants.MAX_SIZE().intValue(), "OC-01-001-01-15-009", "分页条数", "最大"+MnOrderCenterConstants.MAX_SIZE().intValue());
        AssertUtils.isTrue(request.getPage() <= 0, "OC-01-001-01-15-009", "页数", "最小值为1");
        AssertUtils.isTrue(request.getSize() <= 0, "OC-01-001-01-15-009", "分页条数", "最小值为1");
    }

    private void checkItemLength(List<String> items, Integer maxLength, String errMsg) {
        items.forEach(x -> {
            AssertUtils.lengthCheck(x, maxLength, false, "OC-01-001-01-15-004", errMsg);
        });
    }

    private void paramsCheck(OrderAtomQueryListRequest salesOrderAtomQueryListRequest) {
        baseParamsCheck(salesOrderAtomQueryListRequest.getFromSys(),
                salesOrderAtomQueryListRequest.getBusinessUnitCode(),
                salesOrderAtomQueryListRequest.getBusinessType(),
                salesOrderAtomQueryListRequest.getPage(),
                salesOrderAtomQueryListRequest.getSize());
        // 多个单号取交集
        List<String> salesOrderNo = salesOrderAtomQueryListRequest.getSalesOrderNo();
        List<String> outOrderNo = salesOrderAtomQueryListRequest.getOutOrderNo();
        if (CollectionUtils.isEmpty(salesOrderNo) && CollectionUtils.isEmpty(outOrderNo)) {
            throw new FunctionException("OC-01-001-01-15-001", "退货订单单号、外部单号", "同时");
        }
        for (String x : salesOrderNo) {
            AssertUtils.lengthCheck(x, 50, false, "OC-01-001-01-15-004", "退货单单号");
        }
        for (String x : outOrderNo) {
            AssertUtils.lengthCheck(x, 50, false, "OC-01-001-01-15-004", "外部单号");
        }
    }

    private void filterBlankOrderNo(OrderAtomQueryListRequest orderAtomQueryListRequest) {
        List<String> sourceOrderNo = orderAtomQueryListRequest.getSourceOrderNo();
        List<String> salesOrderNo = orderAtomQueryListRequest.getSalesOrderNo();
        List<String> preOrderNo = orderAtomQueryListRequest.getPreOrderNo();
        List<String> outOrderNo = orderAtomQueryListRequest.getOutOrderNo();
        List<String> deliveryOrderNo = orderAtomQueryListRequest.getDeliveryOrderNo();

        sourceOrderNo = Optional.ofNullable(sourceOrderNo).orElse(Lists.newArrayList()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        salesOrderNo = Optional.ofNullable(salesOrderNo).orElse(Lists.newArrayList()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        preOrderNo = Optional.ofNullable(preOrderNo).orElse(Lists.newArrayList()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        outOrderNo = Optional.ofNullable(outOrderNo).orElse(Lists.newArrayList()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        deliveryOrderNo = Optional.ofNullable(deliveryOrderNo).orElse(Lists.newArrayList()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());

        orderAtomQueryListRequest.setSourceOrderNo(sourceOrderNo);
        orderAtomQueryListRequest.setSalesOrderNo(salesOrderNo);
        orderAtomQueryListRequest.setPreOrderNo(preOrderNo);
        orderAtomQueryListRequest.setOutOrderNo(outOrderNo);
        orderAtomQueryListRequest.setDeliveryOrderNo(deliveryOrderNo);
    }
}
